The security of operation of many cryptographic applications relies on the unpredictability of certain quantities generated every time they are used. The examples include secret keys for symmetric encryption algorithms, the parameters of the RSA and auxiliary quantities for digital signature generation.
A simple and widely used class is linear congruential generators (LCG), which can be defined as follows:
In[14]:=
SeedRandom[1,Method->{"Congruential","Multiplier"->
16
2
+3,"Increment"->0,"Modulus"->
31
2
}];
The first 10 pseudorandom integers it will produce from the seed 1 by repeated evaluation would be:
In[15]:=
BlockRandom[RandomInteger[
31
2
-1,10]]
Out[15]=
{65539,393225,1769499,7077969,26542323,95552217,334432395,1146624417,1722371299,14608041}
On a large scale, the numbers produced do look as if they were uniformly distributed and random, even though they were computed using a deterministic algorithm:
In[19]:=
ListPlot[RandomReal[1,10000]]
Out[19]=
2000
4000
6000
8000
10000
0.2
0.4
0.6
0.8
1.0
The parameters Multiplier, Increment and Modulus used in
SeedRandom
above are those of an infamous generator, RANDU, considered one of weakest ever designed.
When its outputs are taken as triplets
{
x
n-1
,
x
n
,
x
n+1
} (the previous output, the current one and the next one), it can be clearly seen that these points only fall into several planes, which cannot be considered random:
In[20]:=
ListPointPlot3D[Partition[RandomReal[1,100000],3,2]]
Out[20]=
High quality of underlying sources of pseudorandomness is crucial for cryptographic features of Wolfram Language, such as
GenerateSymmetricKey
,
GenerateAsymmetricKeyPair
and
GenerateDerivedKey
. These functions use cryptographically secure pseudo random generator (CSPRNG) provided by OpenSSL to fetch cryptographically strong random bytes:
In[22]:=
SeedRandom[Method->"OpenSSL"];
In[12]:=
GenerateSymmetricKey[]
Out[12]=
SymmetricKey
Cipher: AES256
Key size:
256
b

In[11]:=
BaseEncode[%["Key"]]
Out[11]=
7TjXZZwQ/+1fiZ9tLD7HmMh0qzBOEHqdhgIYm8OxK+A=
In[12]:=
GenerateSymmetricKey[]
Out[12]=
SymmetricKey
Cipher: AES256
Key size:
256
b

In[11]:=
BaseEncode[%["Key"]]
Out[11]=
7TjXZZwQ/+1fiZ9tLD7HmMh0qzBOEHqdhgIYm8OxK+A=
In[22]:=
GenerateAsymmetricKeyPair[]
Out[22]=
PrivateKeyPrivateKey
Type: RSA
Public modulus size:
2048
b
Private exponent size:
2048
b
,PublicKeyPublicKey
Type: RSA
Public modulus size:
2048
b

In[23]:=
%["PrivateKey"]["PrivateHexString"]
Out[23]=
7d26edc7c1ccf234083ffd45e2c32270ecd0b6c09799792dfb4a2e3e083d6a49775c4e7627673eb319bdcd2d801d29af964695eec9c6a4905ec1ca56b9fb9365dc784bc19b14f49a95379e47467ffba64c54e2849dd3eae93dc6a522e016294366e8f3afd0581db8643684947e758b2630edbffe1eb4beb7763084dd7550dbe556539e31a287fc66d24eb17e881cfa279631d70359cd9df57c626ee1debcf1daf7443188ce8a96442c00aec27b3980f8bf58375982519fefc9ba313731ac9799caa0a706f963b4a2236a4c9630f0d311bdbf8cf192aef2a05f35c80c60716b79fab8f1e8aee8cc8c14df6623217ba84be626a4cab03f292a4c3890f2b576b8cd